package com.qqt.csr.im.service.sensitiveword;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.github.houbb.sensitive.word.api.IWordDeny;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
import com.github.houbb.sensitive.word.support.allow.WordAllows;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@Component("sensitiveWordBsFactory")
public class SensitiveWordBsFactory implements InitializingBean {
    private final Map<String, SensitiveWordBs> sensitiveWordBsMap = new ConcurrentHashMap<>();

    @Autowired
    private SensitiveWordService sensitiveWordService;
    @Autowired
    private SensitiveWordTagService sensitiveWordTagService;

    @Override
    public void afterPropertiesSet() throws Exception {
        List<String> tenantIdList = sensitiveWordService.getAllTenantIdList();
        if (CollectionUtils.isEmpty(tenantIdList)) {
            return;
        }

        ExecutorService executor = new ThreadPoolExecutor(Math.max(10, tenantIdList.size()), 100,
                60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(tenantIdList.size()),
                new ThreadFactoryBuilder().setNamePrefix("sw-pool-").build(), new ThreadPoolExecutor.CallerRunsPolicy());

        List<Future<?>> futureList = new ArrayList<>();
        for (String tenantId : tenantIdList) {
            Future<?> future = executor.submit(() -> {
                createSensitiveWordBs(tenantId);
            });
            futureList.add(future);
        }

        for (Future<?> future : futureList) {
            future.get();
        }
        executor.shutdown();
    }

    /**
     * 获取租户的敏感词工具
     *
     * @param tenantId
     * @return
     */
    public SensitiveWordBs getSensitiveWordBs(String tenantId) {
        return sensitiveWordBsMap.computeIfAbsent(tenantId, this::createSensitiveWordBs);
    }

    /**
     * 创建租户敏感词工具
     *
     * @param tenantId
     */
    private SensitiveWordBs createSensitiveWordBs(String tenantId) {
        SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance()
                .enableEmailCheck(false)
                .enableIpv4Check(false)
                .enableNumCheck(false)
                .enableUrlCheck(false)
                .wordAllow(WordAllows.empty())
                .wordTag(sensitiveWordTagService)
                .wordDeny(() -> sensitiveWordService.denyBy(tenantId))
                .init();
        sensitiveWordBsMap.put(tenantId, sensitiveWordBs);
        return sensitiveWordBs;
    }
}
